package com.example.demo.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;

/**
 * 日期工具类
 *
 * @author zengqingfa
 */
public class DateTools {

    public static final String pattern = "yyyy-MM-dd HH:mm:ss";
    public static final String DAY_PATTERN = "yyyy-MM-dd";

    /**
     * 日期转化为指定日期格式类型
     *
     * @param date    日期
     * @param pattern 日期格式类型，如yyyy-MM-dd，yyyy年MM月dd日 HH:mm:ss
     * @return
     */
    public static String dateToString(Date date, String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);//日期格式
        String date_str = sdf.format(date);//日期转化为指定格式
        return date_str;
    }

    /**
     * 获取指定时间格式的字符串
     *
     * @param date
     * @return
     */
    public static String defaultDateToString(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);//日期格式
        String date_str = sdf.format(date);//日期转化为指定格式
        return date_str;
    }

    /**
     * 日期字符串转化为指定日期格式类型
     *
     * @param date_str 日期字符串
     * @param pattern  日期格式类型，如yyyy-MM-dd，yyyy年MM月dd日 HH:mm:ss
     * @return
     * @throws ParseException
     */
    public static Date stringToDate(String date_str, String pattern) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);//日期格式
        Date date = sdf.parse(date_str);//日期转化为指定格式
        return date;
    }

    /**
     * 获得今天日期
     *
     * @param pattern 日期格式类型，如yyyy-MM-dd，yyyy年MM月dd日 HH:mm:ss
     * @return
     */
    public static String getToday(String pattern) {
        Date date = new Date();//今天日期
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);//日期格式
        String today = sdf.format(date);//日期转化为指定格式
        return today;
    }

    /**
     * 获得明天日期
     *
     * @param pattern 日期格式类型，如yyyy-MM-dd，yyyy年MM月dd日 HH:mm:ss
     * @return
     */
    public static String getTomorrow(String pattern) {
        Date date = new Date();//今天日期
        Calendar cal = new GregorianCalendar();
        cal.setTime(date);//设置时间
        cal.add(Calendar.DATE, 1);//把日期往后增加一天.整数往后推,负数往前移动
        date = cal.getTime();//这个时间就是日期往后推一天的日期结果，即明天日期
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);//日期格式
        String tommorrow = sdf.format(date);//明天日期
        return tommorrow;
    }

    /**
     * 获得昨天日期
     *
     * @param pattern 日期格式类型，如yyyy-MM-dd，yyyy年MM月dd日 HH:mm:ss
     * @return
     */
    public static String getYesterday(String pattern) {
        Date date = new Date();//今天日期
        Calendar cal = new GregorianCalendar();
        cal.setTime(date);//设置时间
        cal.add(Calendar.DATE, -1);//把日期往后增加一天.整数往后推,负数往前移动
        date = cal.getTime();//这个时间就是日期往前推一天的日期结果，即昨天日期
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);//日期格式
        String yesterday = sdf.format(date);//昨天日期
        return yesterday;
    }

    /**
     * 获得指定日期的后一天
     *
     * @param date    指定日期
     * @param pattern 日期格式类型，如yyyy-MM-dd，yyyy年MM月dd日 HH:mm:ss
     * @return
     * @throws ParseException
     */
    public static Date getAfterDay(Date date, String pattern) throws ParseException {
        Calendar cal = new GregorianCalendar();
        cal.setTime(date);//设置时间
        cal.add(Calendar.DATE, 1);//把日期往后增加一天.整数往后推,负数往前移动
        date = cal.getTime();//这个时间就是日期往后推一天的日期结果，即后一天日期
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);//日期格式
        String next_date_str = sdf.format(date);//后一天日期
        //将日期字符串转化为指定日期格式类型
        Date after_date = stringToDate(next_date_str, pattern);
        return after_date;
    }

    /**
     * 获得指定日期的后一天
     *
     * @param date_str 指定日期字符串
     * @param pattern  日期格式类型，如yyyy-MM-dd，yyyy年MM月dd日 HH:mm:ss
     * @return
     * @throws ParseException
     */
    public static String getAfterDay(String date_str, String pattern) throws ParseException {
        //将日期字符串转化为指定日期格式类型
        Date date = stringToDate(date_str, pattern);
        Calendar cal = new GregorianCalendar();
        cal.setTime(date);//设置时间
        cal.add(Calendar.DATE, 1);//把日期往后增加一天.整数往后推,负数往前移动
        date = cal.getTime();//这个时间就是日期往后推一天的日期结果，即后一天日期
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);//日期格式
        String after_date_str = sdf.format(date);//后一天日期
        return after_date_str;
    }

    /**
     * 获得指定日期的前一天
     *
     * @param date    指定日期
     * @param pattern 日期格式类型，如yyyy-MM-dd，yyyy年MM月dd日 HH:mm:ss
     * @return
     * @throws ParseException
     */
    public static Date getBeforetDay(Date date, String pattern) throws ParseException {
        Calendar cal = new GregorianCalendar();
        cal.setTime(date);//设置时间
        cal.add(Calendar.DATE, -1);//把日期往后增加一天.整数往后推,负数往前移动
        date = cal.getTime();//这个时间就是日期往后推一天的日期结果，即前一天日期
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);//日期格式
        String before_date_str = sdf.format(date);//前一天日期
        //将日期字符串转化为指定日期格式类型
        Date before_date = stringToDate(before_date_str, pattern);
        return before_date;
    }

    /**
     * 获得指定日期的前一天
     *
     * @param date_str 指定日期字符串
     * @param pattern  日期格式类型，如yyyy-MM-dd，yyyy年MM月dd日 HH:mm:ss
     * @return
     * @throws ParseException
     */
    public static String getBeforeDay(String date_str, String pattern) throws ParseException {
        //将日期字符串转化为指定日期格式类型
        Date date = stringToDate(date_str, pattern);
        Calendar cal = new GregorianCalendar();
        cal.setTime(date);//设置时间
        cal.add(Calendar.DATE, -1);//把日期往后增加一天.整数往后推,负数往前移动
        date = cal.getTime();//这个时间就是日期往后推一天的日期结果，即前一天日期
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);//日期格式
        String before_date_str = sdf.format(date);//前一天日期
        return before_date_str;
    }



    public static void main(String[] args) {
        /**
         * 返回值如下：
         *          2023-01-02 00:00:00=2023-01-08 23:59:59
         *          2023-01-03 00:00:00=2023-01-03 23:59:59
         *          2023-01-04 00:00:00=2023-01-04 23:59:59
         */
        String[] currentWeekTimeFrame = getCurrentWeekTimeFrame();
        System.out.println(currentWeekTimeFrame[0]+"="+currentWeekTimeFrame[1]);

        String[] currentDayTimeFrame = getCurrentDayTimeFrame(0);
        System.out.println(currentDayTimeFrame[0]+"="+currentDayTimeFrame[1]);

        String[] currentDayTimeFrame1 = getCurrentDayTimeFrame(1);
        System.out.println(currentDayTimeFrame1[0]+"="+currentDayTimeFrame1[1]);
    }

    /**
     * 当前时间一周的开始时间和结束时间
     * @return 时间数组：开始时间和结束时间字符串格式yyyy-MM-dd HH:mm:ss数组
     *      2023-01-04 00:00:00,2023-01-04 23:59:59
     */
    public static String[] getCurrentWeekTimeFrame() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        //start of the week
        if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
            calendar.add(Calendar.DAY_OF_YEAR, -1);
        }
        calendar.add(Calendar.DAY_OF_WEEK, -(calendar.get(Calendar.DAY_OF_WEEK) - 2));
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);

        Date startTime = calendar.getTime();
        //end of the week
        calendar.add(Calendar.DAY_OF_WEEK, 6);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        Date endTime = calendar.getTime();
        return new String[]{defaultDateToString(startTime), defaultDateToString(endTime)};
    }

    /**
     * @param amount 表示当前加几天
     * @return
     */
    public static String[] getCurrentDayTimeFrame(int amount) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        calendar.add(Calendar.DATE, amount);//把日期往后增加一天.整数往后推,负数往前移动
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);

        Date startTime = calendar.getTime();
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        Date endTime = calendar.getTime();
        return new String[]{defaultDateToString(startTime), defaultDateToString(endTime)};
    }
}